//
//  PushManager.m
//  18Birdies
//
//  Created by Lc on 15/7/6.
//  Copyright (c) 2015年 Lc. All rights reserved.
//

#import <UserNotifications/UserNotifications.h>
#import "LcFoundation.h"
#import "AppDelegate.h"
#import "BackgroundRequestManager.h"
#import "PushManager.h"
#import "UserManager.h"

@interface PushManager () <LcNotificationDelegate>
@property(nonatomic, strong) LcNotificationCenter* notificationCenter;
@property(nonatomic, strong) LcPersistenceCenter* persistenceCenter;
@property(nonatomic, strong) UserManager* userManager;
@property(nonatomic, strong) BackgroundRequestManager* backgroundRequestManager;

@property(nonatomic, assign) BOOL isRequestingPushMessages;
@property(nonatomic, strong) NSThread* thread;
// for checking duplicated push messages from server
@property(nonatomic, strong) NSMutableSet* processedPushMessages;
// save older processedPushMessages
@property(nonatomic, strong) NSMutableSet* processedPushMessages2;

@property(nonatomic, assign) BOOL clientVersionTooOld;
@property(nonatomic, strong) NSData* rawDeviceToken;
@end

@implementation PushManager

static LcPersistenceMeta* PUSH_MANAGER_MODEL_META;

+ (void)initialize {
}

- (void)internalInit {
  self.notificationCenter = [LcNotificationCenter sharedInstance];
  self.persistenceCenter = [LcPersistenceCenter sharedInstance];
  self.userManager = [UserManager sharedInstance];
  self.backgroundRequestManager = [BackgroundRequestManager sharedInstance];

  self.processedPushMessages = [NSMutableSet set];
  self.processedPushMessages2 = [NSMutableSet set];

  [self.notificationCenter registerDelegate:self];
}

- (UNAuthorizationStatus)authorizatioStatus {
    UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
    __block UNAuthorizationStatus status = UNAuthorizationStatusNotDetermined;
    dispatch_semaphore_t sema = dispatch_semaphore_create(0);
    [center
     getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings* _Nonnull settings) {
       status = settings.authorizationStatus;
       dispatch_semaphore_signal(sema);
     }];
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
    return status;
}

- (BOOL)authorizationNotDetermined {
  return [self authorizatioStatus] == UNAuthorizationStatusNotDetermined;
}

- (BOOL)authorized {
  return [self authorizatioStatus] == UNAuthorizationStatusAuthorized;
}

- (BOOL)requestAuthorization {
  UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
  center.delegate = [AppDelegate sharedInstance];
  UNAuthorizationOptions options =
      (UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert);
  __block BOOL accessGranted = NO;
  dispatch_semaphore_t sema = dispatch_semaphore_create(0);
  [center requestAuthorizationWithOptions:options
                        completionHandler:^(BOOL granted, NSError* _Nullable error) {
                          accessGranted = granted;
                          dispatch_semaphore_signal(sema);
                        }];
  dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
  [self requestPushAccessToken];
  return accessGranted;
}

- (void)registerAPNSPushCategories {
  UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
  UNNotificationCategory* generalCategory = [UNNotificationCategory
      categoryWithIdentifier:@"GENERAL"
                     actions:@[]
           intentIdentifiers:@[]
                     options:UNNotificationCategoryOptionCustomDismissAction];
  [center setNotificationCategories:[NSSet setWithObject:generalCategory]];
}

- (void)requestPushAccessToken {
  [self registerAPNSPushCategories];
  UIApplication* application = [UIApplication sharedApplication];
  UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
  center.delegate = [AppDelegate sharedInstance];
  [application registerForRemoteNotifications];
}

- (void)setRawDeviceToken:(NSData*)rawDeviceToken {
  if (!rawDeviceToken || ![rawDeviceToken isKindOfClass:[NSData class]] || rawDeviceToken.length==0) {
      return;
  }
  self.rawDeviceToken = rawDeviceToken;
  NSString* deviceToken;
  if (@available(iOS 13.0, *)) {
      const unsigned char *dataBuffer = (const unsigned char *)rawDeviceToken.bytes;
      NSMutableString *token  = [NSMutableString stringWithCapacity:(rawDeviceToken.length * 2)];
      for (int i = 0; i < rawDeviceToken.length; i++) {
          [token appendFormat:@"%02x", dataBuffer[i]];
      }
      deviceToken = token;
  } else {
      NSCharacterSet *characterSet = [NSCharacterSet characterSetWithCharactersInString:@"<>"];
      NSString* token = [[rawDeviceToken description] stringByTrimmingCharactersInSet:characterSet];
      deviceToken = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
  }
  
  LcLog(@"deviceToken=%@", deviceToken);

}

- (NSData*)rawDeviceToken {
  return self.rawDeviceToken;
}

- (void)requestPassivePushes {
  LC_CHECK_IS_MAIN_THREAD();
  if (self.clientVersionTooOld) {
    return;
  }
  if (!self.userManager.isLogined) {
    return;
  }
  if (![AppDelegate sharedInstance].isForeground) {
    return;
  }
  if (self.isRequestingPushMessages) {
    return;
  }
  self.isRequestingPushMessages = YES;
}

- (void)notificationReceived:(NSString*)notification auxiliary:(id)auxiliary {

}

- (void)clear {

}

- (void)startBackgroundThread {
  LC_CHECK_TRUE(self.thread == nil);
  self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
  [self.thread start];
}

- (void)run {

}

@end
